/*

Copyright (C) 2007 Thomas Geiger (tom.geiger@gmail.com)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

#include <octave/oct.h>

#include "octavexml/octave_xml.h"
#include "octavexml/OctaveXMLReader.h"

#include "OGSADAIConnection.h"

using namespace std;

DEFUN_DLD(db_connect, 
          args, 
          , 
          "Opens database connection.\n ret = db_connect('connectionstring', 'username:password')"
          ) 
{		
	int argc;
	string connectionstring;
	string cred;
	
	argc = args.length();
	
	if (argc != 2 || (!args(0).is_string() || !args(1).is_string()) ) {
		cout << "Usage: db_connect('connectionstring', 'username:password') \n";
		return octave_value(false);
	}
	
	connectionstring = args(0).string_value();
	cred = args(1).string_value();
	
	OGSADAIConnection* conn = OGSADAIConnection::GetConnection();
	if (conn != NULL) {
		if (conn->open(connectionstring, cred)) {
			return octave_value(true);
		}		
		return octave_value(false);
	}
	cout << "Could not obtain a connection." << endl;
	return octave_value(false);	                                            
}

DEFUN_DLD(db_close, 
          args, 
          , 
          "Closes database connection.\nret = db_close()"
          ) 
{	
	OGSADAIConnection* conn = OGSADAIConnection::GetConnection();
	if (conn != NULL) {
		
		if (conn->isConnected()) {	
			conn->close();
		} else {
			cout << "Connection already closed." << endl;
		}
		
		return octave_value(true);
	}
	cout << "Could not obtain a connection." << endl;
	return octave_value(false);	                                            
}

DEFUN_DLD(db_query, 
          args, 
          , 
          "Execute query statement against database.\nret = db_query('SELECT * from myTable')\nSELECT, DESCRIBE, ..."
          ) 
{	
	octave_value_list retval;
	int argc;
	string result = "";
	string statement;
	
	argc = args.length();
	
	if (argc != 1 || !args(0).is_string() ) {
		cout << "Usage: db_query('statement') \n";
		return octave_value(false);
	}
	
	statement = args(0).string_value();
	

	OGSADAIConnection* conn = OGSADAIConnection::GetConnection();
	if (conn != NULL) {
		
		if (conn->isConnected()) {
			result = conn->executeQuery(statement);

			//cout << "RESULT:" << endl << result << endl;
		} else {
			cout << "No connection. Try db_connect() first." << endl;
			return octave_value(false);
		}
		
		if (result != "") {
			istringstream data(result, istringstream::in);
			octave_value_list values;
			OctaveXMLReader reader;
			reader.setFormat(FMT_TYPESAFE);
			reader.readXML(data, values);
			return values;
		}
		return octave_value(false);
	}
	cout << "Could not obtain a connection." << endl;
	return octave_value(false);	                                            
}

DEFUN_DLD(db_update, 
          args, 
          , 
          "Execute update statement against database.\nret = db_update('...')\nINSERT, UPDATE, ..."
          ) 
{		
	octave_value_list retval;
	int argc;
	string result = "";
	string statement;
	
	argc = args.length();
	
	if (argc != 1 || !args(0).is_string() ) {
		cout << "Usage: db_update('statement') \n";
		return octave_value(false);
	}
		
	statement = args(0).string_value();
	
	OGSADAIConnection* conn = OGSADAIConnection::GetConnection();
	if (conn != NULL) {
		
		if (conn->isConnected()) {
			result = conn->executeUpdate(statement);
			
		} else {
			cout << "No connection. Try db_connect() first." << endl;
			return octave_value(false);
		}
		
		if (result != "") {
			// convert to ov and return
			istringstream data(result, istringstream::in);
			octave_value_list values;
			OctaveXMLReader reader;
			reader.setFormat(FMT_TYPESAFE);
			reader.readXML(data, values);
			return values;
		}
		return octave_value(false);
	}
	cout << "Could not obtain a connection." << endl;
	return octave_value(false);	                                            
}

DEFUN_DLD(db_help, 
        args, 
        , 
        "Show information for Octave Data Toolbox functions."
        ) 
{		
	cout << "db_help:" << endl;
	cout << endl;
	cout << "Octave Data Toolbox 0.3" << endl; 
	cout << endl;
	cout << " - db_connect - Open database connection." << endl;
	cout << " - db_close   - Close database connection" << endl;
	cout << " - db_query   - Execute query statement against database." << endl;
	cout << " - db_update  - Execute update statement against database." << endl;
	cout << endl;
	
	return octave_value(true);	                                            
}

